#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <time.h>
#define PORT 1234
#define BACKLOG 2
#define MAXDATASIZE 1000
void process_cli(int connectfd,struct sockaddr_in client);
void sig_handler(int s);
int main()
{
    int opt,listenfd,connectfd;
    pid_t pid;
    struct sockaddr_in server;
    struct sockaddr_in client;
    int sin_size;
    struct sigaction act;
    struct sigaction oact;
    act.sa_handler=sig_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;
    printf("NAME :20155317\n");
    if(sigaction(SIGCHLD,&act,&oact)<0)
    {
        perror("Sigaction failed!\n");
        exit(1);
    }
    if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("Creating socket failed.\n");
        exit(1);
    }
    opt=SO_REUSEADDR;
    setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    bzero(&server,sizeof(server));
    server.sin_family=AF_INET;
    server.sin_port=htons(PORT);
    server.sin_addr.s_addr=htonl(INADDR_ANY);
    if(bind(listenfd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1)
    {
        perror("Bind error.\n");
        exit(1);
    }
    if(listen(listenfd,BACKLOG)==-1)
    {
        perror("listen() error.\n");
        exit(1);
    }
    sin_size=sizeof(struct sockaddr_in);
    while(1)
    {
        if((connectfd=accept(listenfd,(struct sockaddr *)&client,&sin_size))==-1)
        {
            if(errno==EINTR) continue;
            perror("accept() error.\n");
            exit(1);
        }
        if((pid=fork())>0)
        {
            close(connectfd);
            continue;
        }
        else if(pid==0)
        {
            close(listenfd);
            process_cli(connectfd,client);
            exit(0);
        }
        else
        {
            printf("fork error.\n");
            exit(1);
        }
    }
    close(listenfd);
    return 0;
}
void process_cli(int connectfd,struct sockaddr_in client)
{
    int i,num;
    char recvbuf[MAXDATASIZE];
    char sendbuf[MAXDATASIZE];
    char cli_name[MAXDATASIZE];
    time_t t;
    t=time(NULL);
    printf("server IP%s \n",inet_ntoa(client.sin_addr));
    
    num=recv(connectfd,cli_name,MAXDATASIZE,0);
    if(num==0)
    {
        close(connectfd);
        printf("Client disconnected.\n");
        return;
    }
    send(connectfd,(void *)&t,sizeof(time_t),0);
    while(num=recv(connectfd,recvbuf,MAXDATASIZE,0))
    {
        recvbuf[num]='\0';
        printf("TIME:%s\n",ctime(&t));
        //send(connectfd,(void *)&t,sizeof(time_t),0);
    }
    
    close(connectfd);
}
void sig_handler(int s)
{
    pid_t pid;
    int stat;
    while((pid=waitpid(-1,&stat,WNOHANG))>0)
        printf("son process%d closed\n",pid);
    return;
}
